import prisma from '../../api/prisma';

import type { Video, VideoType, Prisma } from '@prisma/client';
import { isVip } from '../../auth/auth-utils';

// 类型定义
export interface VideoTypeWithChildren extends VideoType {
  children: VideoType[];
}

// 部分Video类型，用于select查询结果
export type VideoSelect = Partial<Video>;

// 扩展Prisma类型以支持新字段
type VideoTypeWhereWithNewFields = Prisma.VideoTypeWhereInput & {
  isVisible?: boolean;
  isVip?: boolean;
};

type VideoWhereWithNewFields = Prisma.VideoWhereInput & {
  isVisible?: boolean;
  isVip?: boolean;
};

export class VideoRepository {
  /**
   * 获取所有可见分类
   */
  static async getAllVisibleTypes(): Promise<VideoType[]> {
    // 获取可见分类条件
    const visibleCondition = await this.getVisibleTypeCondition();

    // 根据条件过滤分类
    return await prisma.videoType.findMany({
      where: visibleCondition,
      orderBy: {
        sort: 'asc'
      },
    });
  }

  /**
   * 获取用户可见的分类ID
   * @returns 可见分类ID数组
   */
  static async getAllowedTypeIds(): Promise<number[]> {
    const visibleTypes = await this.getAllVisibleTypes();
    return visibleTypes.map(type => type.id);
  }

  /**
   * 获取可见分类的条件查询对象
   * @returns Prisma查询条件对象
   */
  private static async getVisibleTypeCondition(): Promise<VideoTypeWhereWithNewFields> {
    // 直接在方法内部获取VIP状态
    const is_vip = await isVip();

    return {
      isVisible: true,  // 只查询可见分类
      ...(is_vip ? {} : { isVip: false })  // 非VIP用户只能看到非VIP分类
    };
  }

  /**
   * 获取轮播图视频数据
   * 直接使用可见性字段进行查询
   */
  static async getCarouselVideos(limit = 5): Promise<VideoSelect[]> {
    // 获取用户VIP状态
    const is_vip = await isVip();

    const where: VideoWhereWithNewFields = {
      isCarousel: true,
      carouselPic: {
        not: ''
      },
      isVisible: true,  // 只查询可见视频
      ...(is_vip ? {} : { isVip: false })  // 非VIP用户只能看到非VIP视频
    };

    return await prisma.video.findMany({
      where: where,
      orderBy: [
        { vodHits: 'desc' },
        { vodTime: 'desc' },
      ],
      take: limit,
      select: {
        id: true,
        vodName: true,
        vodPic: true,
        carouselPic: true,
        vodContent: true,
        vodSub: true,
        vodScore: true,
        vodYear: true,
        typeName: true,
        isVip: true
      }
    });
  }

  /**
   * 获取最新视频
   * 直接使用可见性字段进行查询
   */
  static async getNewestVideos(limit = 12): Promise<VideoSelect[]> {
    // 获取用户VIP状态
    const is_vip = await isVip();

    const where: VideoWhereWithNewFields = {
      isVisible: true,  // 只查询可见视频
      ...(is_vip ? {} : { isVip: false })  // 非VIP用户只能看到非VIP视频
    };

    return await prisma.video.findMany({
      where: where,
      orderBy: [
        { vodTime: 'desc' },
        { vodHits: 'desc' }
      ],
      take: limit,
      select: {
        id: true,
        vodName: true,
        vodPic: true,
        vodScore: true,
        vodYear: true,
        typeName: true,
        typeId: true,
        vodRemarks: true,
        isVip: true
      }
    });
  }

  /**
   * 获取最新视频(分页版)
   * 直接使用可见性字段进行查询
   */
  static async getNewestVideosPaged(page = 1, pageSize = 24): Promise<{ videos: VideoSelect[]; total: number }> {
    const skip = (page - 1) * pageSize;

    // 获取用户VIP状态
    const is_vip = await isVip();

    // 获取当天的起始时间（当天的00:00:00）
    const today = new Date();
    today.setHours(0, 0, 0, 0);

    const where: VideoWhereWithNewFields = {
      isVisible: true,  // 只查询可见视频
      ...(is_vip ? {} : { isVip: false }),  // 非VIP用户只能看到非VIP视频
      vodTime: {
        gte: today // 只获取当天的数据
      }
    };

    // 使用Promise.all并行执行两个查询
    const [videos, total] = await Promise.all([
      prisma.video.findMany({
        where: where,
        orderBy: [
          { vodTime: 'desc' },
          { vodHits: 'desc' }
        ],
        skip,
        take: pageSize,
        select: {
          id: true,
          vodName: true,
          vodPic: true,
          vodScore: true,
          vodYear: true,
          typeName: true,
          typeId: true,
          vodRemarks: true,
          isVip: true
        }
      }),
      prisma.video.count({
        where: where
      })
    ]);

    return { videos, total };
  }

  /**
   * 获取热门视频
   * 直接使用可见性字段进行查询
   */
  static async getHotVideos(limit = 12): Promise<VideoSelect[]> {
    // 获取用户VIP状态
    const is_vip = await isVip();

    const where: VideoWhereWithNewFields = {
      isVisible: true,  // 只查询可见视频
      ...(is_vip ? {} : { isVip: false })  // 非VIP用户只能看到非VIP视频
    };

    return await prisma.video.findMany({
      where: where,
      orderBy: [
        { vodHits: 'desc' },
        { vodTime: 'desc' }
      ],
      take: limit,
      select: {
        id: true,
        vodName: true,
        vodPic: true,
        vodScore: true,
        vodYear: true,
        typeName: true,
        typeId: true,
        vodRemarks: true,
        isVip: true
      }
    });
  }

  /**
   * 获取高分视频
   * 直接使用可见性字段进行查询
   */
  static async getTopRatedVideos(limit = 12): Promise<VideoSelect[]> {
    // 获取用户VIP状态
    const is_vip = await isVip();

    const where: VideoWhereWithNewFields = {
      isVisible: true,  // 只查询可见视频
      ...(is_vip ? {} : { isVip: false })  // 非VIP用户只能看到非VIP视频
    };

    return await prisma.video.findMany({
      where: where,
      orderBy: [
        { vodScore: 'desc' },
        { vodTime: 'desc' }
      ],
      take: limit,
      select: {
        id: true,
        vodName: true,
        vodPic: true,
        vodScore: true,
        vodYear: true,
        typeName: true,
        typeId: true,
        vodRemarks: true,
        isVip: true
      }
    });
  }

  /**
   * 获取分类信息（包含子分类）
   * 增加了过滤可见子分类的功能
   */
  static async getTypeWithChildren(typeId: number): Promise<VideoTypeWithChildren | null> {
    const visibleTypeCondition = await this.getVisibleTypeCondition();

    const type = await prisma.videoType.findUnique({
      where: { id: typeId },
      include: {
        children: {
          where: visibleTypeCondition, // 只包含可见的子分类
          orderBy: { sort: 'asc' }
        }
      }
    });

    return type as VideoTypeWithChildren | null;
  }

  /**
   * 获取单个分类信息（不包含子分类）
   */
  static async getSingleType(typeId: number): Promise<VideoType | null> {
    const visibleTypeCondition = await this.getVisibleTypeCondition();

    // 使用findFirst而不是findUnique，因为需要应用可见性过滤
    const type = await prisma.videoType.findFirst({
      where: {
        id: typeId,
        ...visibleTypeCondition
      }
    });

    return type;
  }

  /**
   * 根据分类ID获取视频列表
   * 使用可见性字段代替关联查询
   */
  static async getVideosByTypeIds(
    typeIds: number[],
    page = 1,
    pageSize = 24,
    filters: {
      years?: string[];
      areas?: string[];
      sort?: 'newest' | 'hot' | 'rating';
      yearLessThan?: string;
      yearGreaterThan?: string;
    } = {}
  ): Promise<{ videos: VideoSelect[]; total: number }> {
    // 计算分页
    const skip = (page - 1) * pageSize;

    // 获取用户VIP状态
    const is_vip = await isVip();

    // 基本可见性条件
    const visibilityCondition: VideoWhereWithNewFields = {
      isVisible: true,
      ...(is_vip ? {} : { isVip: false })
    };

    // 构建筛选条件
    const whereCondition: VideoWhereWithNewFields = visibilityCondition;

    // 添加分类ID筛选
    if (typeIds && typeIds.length > 0) {
      whereCondition.typeId = { in: typeIds };
    }

    // 准备年份筛选条件
    const yearFilters = [];

    // 添加具体年份筛选条件
    if (filters.years && filters.years.length > 0) {
      yearFilters.push({ vodYear: { in: filters.years } });
    }

    // 添加"更早"年份筛选条件
    if (filters.yearLessThan) {
      yearFilters.push({
        AND: [
          { vodYear: { lt: filters.yearLessThan } },
          { vodYear: { not: null } },
          { vodYear: { not: '' } }
        ]
      });
    }

    // 添加"最新"年份筛选条件
    if (filters.yearGreaterThan) {
      yearFilters.push({
        vodYear: { gt: filters.yearGreaterThan }
      });
    }

    // 应用年份筛选条件
    if (yearFilters.length > 0) {
      whereCondition.OR = yearFilters;
    }

    // 添加地区筛选
    if (filters.areas && filters.areas.length > 0) {
      whereCondition.vodArea = { in: filters.areas };
    }

    // 确定排序方式
    let orderBy: Prisma.VideoOrderByWithRelationInput[] = [{ vodTime: 'desc' }];

    if (filters.sort === 'hot') {
      orderBy = [{ vodHits: 'desc' }, { vodTime: 'desc' }];
    } else if (filters.sort === 'rating') {
      orderBy = [{ vodScore: 'desc' }, { vodTime: 'desc' }];
    }

    const [videos, total] = await Promise.all([
      prisma.video.findMany({
        where: whereCondition,
        orderBy,
        skip,
        take: pageSize,
        select: {
          id: true,
          vodName: true,
          vodPic: true,
          vodScore: true,
          vodYear: true,
          vodArea: true,
          typeName: true,
          typeId: true,
          vodRemarks: true,
          isVip: true
        }
      }),
      prisma.video.count({
        where: whereCondition
      })
    ]);

    return { videos, total };
  }

  /**
   * 获取视频详情（包含类型信息）
   */
  static async getVideoWithType(id: number): Promise<(Video & { type: VideoType }) | null> {
    return await prisma.video.findUnique({
      where: { id },
      include: { type: true }
    });
  }

  /**
   * 增加视频点击量
   */
  static async increaseHits(id: number): Promise<void> {
    // 添加await以确保操作完成
    await prisma.video.update({
      where: { id },
      data: {
        vodHits: {
          increment: 1
        }
      }
    });
  }

  /**
   * 搜索视频
   * 使用可见性字段代替关联查询
   */
  static async searchVideos(keyword: string, page = 1, pageSize = 24): Promise<{ videos: VideoSelect[]; total: number }> {
    const skip = (page - 1) * pageSize;

    // 获取用户VIP状态
    const is_vip = await isVip();

    // 基本可见性条件
    const visibilityCondition: VideoWhereWithNewFields = {
      isVisible: true,
      ...(is_vip ? {} : { isVip: false })
    };

    // 利用数据库全文索引
    const searchCondition: Prisma.VideoWhereInput = {
      AND: [
        {
          OR: [
            // 使用基于数据库全文索引的优化查询
            {
              vodName: {
                contains: keyword
              }
            },
            {
              vodSub: {
                contains: keyword
              }
            },
            {
              vodEnname: {
                contains: keyword
              }
            },
            {
              vodActor: {
                contains: keyword
              }
            },
            {
              vodDirector: {
                contains: keyword
              }
            }
          ]
        },
        visibilityCondition
      ]
    };

    // 使用select限制返回的字段，提高查询性能
    const [videos, total] = await Promise.all([
      prisma.video.findMany({
        where: searchCondition,
        orderBy: { vodTime: 'desc' },
        skip,
        take: pageSize,
        select: {
          id: true,
          vodName: true,
          vodEnname: true,
          vodSub: true,
          vodPic: true,
          typeId: true,
          typeName: true,
          vodLang: true,
          vodArea: true,
          vodYear: true,
          vodRemarks: true,
          vodActor: true,
          vodDirector: true,
          vodScore: true,
          vodTime: true,
          isVip: true,
          isVisible: true
        }
      }),
      prisma.video.count({
        where: searchCondition
      })
    ]);

    return { videos, total };
  }

  /**
   * 获取相关视频
   * 使用可见性字段代替关联查询
   */
  static async getRelatedVideos(typeId: number, currentId: number, limit = 6): Promise<VideoSelect[]> {
    // 获取用户VIP状态
    const is_vip = await isVip();

    // 基本可见性条件
    const visibilityCondition: VideoWhereWithNewFields = {
      isVisible: true,
      ...(is_vip ? {} : { isVip: false })
    };

    return await prisma.video.findMany({
      where: {
        AND: [
          { typeId },
          { id: { not: currentId } },
          visibilityCondition
        ]
      },
      orderBy: [
        { vodTime: 'desc' },
        { vodHits: 'desc' },
        { vodScore: 'desc' },
      ],
      take: limit,
      select: {
        id: true,
        vodName: true,
        vodPic: true,
        vodScore: true,
        vodYear: true,
        typeName: true,
        typeId: true,
        vodRemarks: true,
        isVip: true
      }
    });
  }

  /**
   * 获取视频年份列表（用于筛选）
   */
  static async getYearsList(): Promise<string[]> {
    // 获取用户VIP状态
    const is_vip = await isVip();

    // 基本可见性条件
    const visibilityCondition: VideoWhereWithNewFields = {
      isVisible: true,
      ...(is_vip ? {} : { isVip: false })
    };

    // 获取所有不同的年份
    const years = await prisma.video.findMany({
      where: visibilityCondition,
      select: {
        vodYear: true
      },
      distinct: ['vodYear']
    });

    // 过滤空值并排序
    return years
      .map(y => y.vodYear)
      .filter((year): year is string => Boolean(year)) // 类型保护，确保过滤掉 null 值
      .sort((a, b) => b.localeCompare(a)); // 降序排列
  }

  /**
   * 获取视频地区列表（用于筛选）
   */
  static async getAreasList(): Promise<string[]> {
    // 获取用户VIP状态
    const is_vip = await isVip();

    // 基本可见性条件
    const visibilityCondition: VideoWhereWithNewFields = {
      isVisible: true,
      ...(is_vip ? {} : { isVip: false })
    };

    // 获取所有不同的地区
    const areas = await prisma.video.findMany({
      where: visibilityCondition,
      select: {
        vodArea: true
      },
      distinct: ['vodArea']
    });

    // 过滤空值并排序
    return areas
      .map(a => a.vodArea)
      .filter((area): area is string => Boolean(area)) // 类型保护，确保过滤掉 null 值
      .sort();
  }

  /**
   * 获取最近24小时内的视频
   * 直接使用可见性字段进行查询
   */
  static async getLast24HoursVideos(page = 1, pageSize = 24): Promise<{ videos: VideoSelect[]; total: number }> {
    const skip = (page - 1) * pageSize;

    try {
      // 获取用户VIP状态
      const is_vip = await isVip();

      // 将时间范围扩大到7天，以确保有数据显示
      const lastDays = new Date();
      lastDays.setDate(lastDays.getDate() - 7); // 改为7天前

      console.log('[DEBUG] 查询最近7天视频，时间范围:', lastDays.toISOString(), ' - ', new Date().toISOString());

      const where: VideoWhereWithNewFields = {
        isVisible: true,  // 只查询可见视频
        ...(is_vip ? {} : { isVip: false }),  // 非VIP用户只能看到非VIP视频
        vodTime: {
          gte: lastDays // 只获取最近7天的数据
        }
      };

      console.log('[DEBUG] 查询条件:', JSON.stringify(where));

      // 使用Promise.all并行执行两个查询
      const [videos, total] = await Promise.all([
        prisma.video.findMany({
          where: where,
          orderBy: [
            { vodTime: 'desc' },
            { vodHits: 'desc' }
          ],
          skip,
          take: pageSize,
          select: {
            id: true,
            vodName: true,
            vodPic: true,
            vodScore: true,
            vodYear: true,
            typeName: true,
            typeId: true,
            vodRemarks: true,
            isVip: true,
            vodTime: true  // 添加时间字段用于调试
          }
        }),
        prisma.video.count({
          where: where
        })
      ]);

      console.log('[DEBUG] 查询结果:', { 总数: total, 视频条数: videos.length });
      
      if (videos.length === 0) {
        // 如果没有数据，查询最新的5个视频（不限时间范围）用于调试
        console.log('[DEBUG] 没有近期视频，尝试查询最新视频（不限时间）');
        const latestVideos = await prisma.video.findMany({
          where: {
            isVisible: true,
            ...(is_vip ? {} : { isVip: false })
          },
          orderBy: { vodTime: 'desc' },
          take: 5,
          select: { 
            id: true, 
            vodName: true, 
            vodTime: true 
          }
        });
        
        console.log('[DEBUG] 最新视频:', latestVideos);
        
        // 如果有最新视频但不在时间范围内，则不使用时间范围限制
        if (latestVideos.length > 0) {
          console.log('[DEBUG] 查询所有可见视频（不限时间）');
          const allVideos = await prisma.video.findMany({
            where: {
              isVisible: true,
              ...(is_vip ? {} : { isVip: false })
            },
            orderBy: [
              { vodTime: 'desc' },
              { vodHits: 'desc' }
            ],
            skip,
            take: pageSize,
            select: {
              id: true,
              vodName: true,
              vodPic: true,
              vodScore: true,
              vodYear: true,
              typeName: true,
              typeId: true,
              vodRemarks: true,
              isVip: true,
              vodTime: true
            }
          });
          
          const allTotal = await prisma.video.count({
            where: {
              isVisible: true,
              ...(is_vip ? {} : { isVip: false })
            }
          });
          
          console.log('[DEBUG] 查询所有视频结果:', { 总数: allTotal, 视频条数: allVideos.length });
          
          // 返回所有视频结果
          return { videos: allVideos, total: allTotal };
        }
      }

      return { videos, total };
    } catch (error) {
      console.error('[ERROR] 获取最近视频失败:', error);
      // 发生错误时返回空结果
      return { videos: [], total: 0 };
    }
  }
}